package com.jebel.framework.classic.event.gateway;

import com.jebel.framwork.common.response.RespBodyBuilder;
import com.jebel.framwork.common.response.RespCode;
import com.jebel.framwork.common.util.JsonUtil;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.eventbus.DeliveryOptions;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.LoggerHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

@Component
public class GateWayVerticle extends AbstractVerticle {

    private static Logger logger = LoggerFactory.getLogger(GateWayVerticle.class);

    @Autowired
    private Environment environment;

    @Override
    public void start() {
        Router router = Router.router(vertx);
        router.route().handler(LoggerHandler.create());
        router.route().handler(BodyHandler.create());

        router.route("/gateway.do").handler(this::doPrEventBusGateway);
        Integer port = Integer.valueOf(environment.getProperty("server.port", "6060"));
        vertx.createHttpServer().requestHandler(router::accept).listen(port);
    }

    private void doPrEventBusGateway(RoutingContext context) {
        HttpServerResponse response = context.response();
        response.putHeader("content-type", "application/json;charset=UTF-8");
        response.putHeader("Access-Control-Allow-Origin", "*");
        response.putHeader("Access-Control-Allow-Methods", "POST,GET");
        response.putHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
        String method = context.request().method().name();
        if (method.equals("OPTIONS")) {
            response.end();
        }
        if (!method.equals("GET") && !method.equals("POST")) {
            response.end();
        }
        JsonObject resp = new JsonObject();
        JsonObject requestBody = method.equals("POST") ? context.getBodyAsJson() : JsonUtil.convertMultiMap(context.request().params());
        try {
            String LID = JsonUtil.getServiceIDBySef(4);
            resp.put("lid", LID);
            requestBody.put("lid", LID);
            logger.info("param:{}", requestBody);
            DeliveryOptions options = new DeliveryOptions();
            options.setSendTimeout(Integer.valueOf(environment.getProperty("vertx.sendimeout", "10000")));
            vertx.eventBus().request(requestBody.getString("service"), requestBody, options, res -> {
                if (res.succeeded()) {
                    resp.mergeIn(new JsonObject(res.result().body().toString()));
                } else {
                    logger.error("error :" + res.cause().getMessage());
                    if (res.cause().getMessage().indexOf("No handlers for address") > -1) {
                        resp.mergeIn(new JsonObject(RespBodyBuilder.toError(RespCode.CODE_10500)));
                    } else {
                        resp.mergeIn(new JsonObject(RespBodyBuilder.toError(RespCode.CODE_10500)));
                    }
                }
                logger.info("reply:{},param:{}", resp.toString(), requestBody);
                resp.remove("lid");
                response.end(resp.toString());
            });
        } catch (Exception e) {
            logger.error("error:{}", e.getMessage());
            response.end(RespBodyBuilder.toError(RespCode.CODE_10500));
        }
    }

}
